/*
 * XXX
 */

package edu.uhcl.csci4838.group3.view;

import java.text.DecimalFormat;
import java.text.NumberFormat;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import edu.uhcl.csci4838.group3.R;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourse;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourseAlert;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourseFaculty;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourseTimeOverride;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorGradingScaleRange;
import edu.uhcl.csci4838.group3.database.info.Course;
import edu.uhcl.csci4838.group3.database.info.CourseAlert;
import edu.uhcl.csci4838.group3.database.info.CourseFaculty;
import edu.uhcl.csci4838.group3.database.info.CourseTimeOverride;
import edu.uhcl.csci4838.group3.database.info.GradingScaleRange;
import edu.uhcl.csci4838.group3.date.DateConstants;
import edu.uhcl.csci4838.group3.date.SimpleTime;
import edu.uhcl.csci4838.group3.view.help.HelpActivity;

/**
 * XXX
 * 
 * @author Chris Waguespack
 */
public class CourseInfoTabActivity extends Activity {
	/**
	 * XXX
	 * 
	 * @author Chris Waguespack
	 */
	private static class AlertViewBinder implements
			SimpleCursorAdapter.ViewBinder {
		
		/**
		 * XXX
		 */
		public AlertViewBinder() {
			// TODO Auto-generated constructor stub
		}
		
		/**
		 * XXX
		 * 
		 * @param view
		 *            XXX
		 * @param cursor
		 *            XXX
		 * @param columnIndex
		 *            XXX
		 * @return XXX
		 */
		/* 
		 * (non-Javadoc)
		 * 
		 * @see android.widget.SimpleCursorAdapter.ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)
		 */
		@Override
		public boolean setViewValue(final View view,
				final Cursor cursor,
				final int columnIndex) {
			switch (view.getId()) {
				case R.id.tv_minutesBefore:
					final int minutes = ((CursorCourseAlert) cursor).getColMinutesBefore();
					final StringBuilder timeString = new StringBuilder();
					
					// Show days
					if (minutes >= 1440) {
						timeString.append(minutes / 1440);
						timeString.append(" d - ");
					}

					// Show hours
					if (minutes >= 60) {
						timeString.append((minutes % 1440) / 60);
						timeString.append(" h - ");
					}
					
					// Show minutes
					timeString.append((minutes % 1440) % 60);
					timeString.append(" m before");
					
					((TextView) view).setText(timeString.toString());
					return true;
				default:
					return false;
			}
		}
	}
	
	/**
	 * XXX
	 * 
	 * @author Chris Waguespack
	 */
	private static class OverrideViewBinder implements
			SimpleCursorAdapter.ViewBinder {
		
		/**
		 * XXX
		 */
		public OverrideViewBinder() {
			// TODO Auto-generated constructor stub
		}
		
		/**
		 * XXX
		 * 
		 * @param view
		 *            XXX
		 * @param cursor
		 *            XXX
		 * @param columnIndex
		 *            XXX
		 * @return XXX
		 */
		/* 
		 * (non-Javadoc)
		 * 
		 * @see android.widget.SimpleCursorAdapter.ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)
		 */
		@Override
		public boolean setViewValue(final View view,
				final Cursor cursor,
				final int columnIndex) {
			switch (view.getId()) {
				case R.id.tv_date:
					final long date = ((CursorCourseTimeOverride) cursor).getColDate();
					((TextView) view).setText(DateFormat.format("MM/dd/yy",
							date));
					return true;
				case R.id.tv_startTime:
					final int startHours = ((CursorCourseTimeOverride) cursor).getColStartTimeHour();
					final int startMinutes = ((CursorCourseTimeOverride) cursor).getColStartTimeMinute();
					final SimpleTime startTime = new SimpleTime(startHours,
							startMinutes);
					((TextView) view).setText(startTime.toString());
					return true;
				case R.id.tv_endTime:
					final int endHours = ((CursorCourseTimeOverride) cursor).getColEndTimeHour();
					final int endMinutes = ((CursorCourseTimeOverride) cursor).getColEndTimeMinute();
					final SimpleTime endTime = new SimpleTime(endHours,
							endMinutes);
					((TextView) view).setText(endTime.toString());
					return true;
				default:
					return false;
			}
		}
	}
	
	/**
	 * The database helper object.
	 */
	private static BackpackEduDatabaseHelper dbHelper;
	
	/**
	 * The course cursor used to populate this view.
	 */
	private CursorCourse courseCursor;
	
	private static TextView tvSemesterName;
	private static TextView tvCourseName;
	private static TextView tvDescription;
	private static TextView tvLocation;
	private static TextView tvWebsite;
	private static TextView tvSchedule;
	private static TextView tvMeetingTimes;
	private static ListView lvOverrides;
	private static ListView lvAlerts;
	private static TableLayout tblGradeScale;
	private static ListView lvFaculty;
	private static TextView tvRssFeed;
	
	/**
	 * XXX
	 * 
	 * @param menu
	 *            XXX
	 * @return XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		this.getMenuInflater()
				.inflate(R.menu.options_courseinfo,
						menu);
		return true;
	}
	
	/**
	 * XXX
	 * 
	 * @param item
	 *            XXX
	 * @return XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		switch (item.getItemId()) {
			case R.id.menu_item_edit_course:
				this.startActivity(new Intent(this.getApplicationContext(),
						EditCourseInfoActivity.class).putExtra(this.getString(R.string.intent_extra_courseId),
						this.courseCursor.getColId()));
				return true;
			case R.id.menu_item_delete_course:
				this.showDeleteCourseDialog();
				return true;
			case R.id.menu_item_settings:
				this.startActivity(new Intent(this.getApplicationContext(),
						SettingsActivity.class));
				return true;
			case R.id.menu_item_about:
				this.startActivity(new Intent(this.getApplicationContext(),
						AboutActivity.class));
				return true;
			case R.id.menu_item_help:
				this.startActivity(new Intent(this.getApplicationContext(),
						HelpActivity.class));
				return true;
			default:
				Log.wtf("BackpackEDU",
						"Undefined options menu item.");
				return super.onOptionsItemSelected(item);
		}
	}
	
	/**
	 * XXX
	 * 
	 * @param savedInstanceState
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.ActivityGroup#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		this.setContentView(R.layout.activity_view_course_info);
		
		// Get components
		CourseInfoTabActivity.tvSemesterName = (TextView) this.findViewById(R.id.textView_semester);
		CourseInfoTabActivity.tvCourseName = (TextView) this.findViewById(R.id.textView_courseName);
		CourseInfoTabActivity.tvDescription = (TextView) this.findViewById(R.id.textView_description);
		CourseInfoTabActivity.tvLocation = (TextView) this.findViewById(R.id.text_set_location);
		CourseInfoTabActivity.tvWebsite = (TextView) this.findViewById(R.id.text_set_website);
		CourseInfoTabActivity.tvSchedule = (TextView) this.findViewById(R.id.text_set_schedule);
		CourseInfoTabActivity.tvMeetingTimes = (TextView) this.findViewById(R.id.text_set_times);
		CourseInfoTabActivity.tvRssFeed = (TextView) this.findViewById(R.id.text_set_rss);
		CourseInfoTabActivity.lvOverrides = (ListView) this.findViewById(R.id.lv_overrides);
		CourseInfoTabActivity.lvAlerts = (ListView) this.findViewById(R.id.lv_alerts);
		CourseInfoTabActivity.tblGradeScale = (TableLayout) this.findViewById(R.id.tbl_gradeScale);
		CourseInfoTabActivity.lvFaculty = (ListView) this.findViewById(R.id.lv_faculty);
		
		// Calling intent
		final Intent callingIntent = this.getIntent();
		final long courseId = callingIntent.getLongExtra(this.getString(R.string.intent_extra_courseId),
				-1);
		
		// Cursor
		CourseInfoTabActivity.dbHelper = new BackpackEduDatabaseHelper(this);
		ContentValues criteria = new ContentValues();
		criteria.put(Course.ID,
				Long.valueOf(courseId));
		this.courseCursor = CourseInfoTabActivity.dbHelper.getCourse(criteria,
				null,
				true);
		this.startManagingCursor(this.courseCursor);
		
		// Populate the fields
		CourseInfoTabActivity.tvSemesterName.setText(this.courseCursor.getColSemesterName());
		CourseInfoTabActivity.tvCourseName.setText(this.courseCursor.getColName());
		
		// Description
		if (this.courseCursor.getColDescription() == null) {
			CourseInfoTabActivity.tvDescription.setVisibility(View.GONE);
		} else {
			CourseInfoTabActivity.tvDescription.setText(this.courseCursor.getColDescription());
		}
		
		// Location
		if (this.courseCursor.getColLocation() == null) {
			this.findViewById(R.id.textView_location).setVisibility(View.GONE);
			CourseInfoTabActivity.tvLocation.setVisibility(View.GONE);
		} else {
			CourseInfoTabActivity.tvLocation.setText(this.courseCursor.getColLocation());
		}
		
		// Website
		if (this.courseCursor.getColWebsite() == null) {
			this.findViewById(R.id.textView_website).setVisibility(View.GONE);
			CourseInfoTabActivity.tvWebsite.setVisibility(View.GONE);
		} else {
			CourseInfoTabActivity.tvWebsite.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(final View v) {
					final Intent i = new Intent(Intent.ACTION_VIEW);
					i.setData(Uri.parse(CourseInfoTabActivity.this.courseCursor.getColWebsite()));
					try {
						CourseInfoTabActivity.this.startActivity(i);
					} catch (final ActivityNotFoundException ex) {
						final Intent chooser = Intent.createChooser(i,
								"Open website...");
						CourseInfoTabActivity.this.startActivity(chooser);
					}
				}
			});
		}
		
		// Schedule
		if ((this.courseCursor.getColStartDate() == null)
				|| (this.courseCursor.getColEndDate() == null)) {
			this.findViewById(R.id.textView_classSchedule).setVisibility(View.GONE);
			CourseInfoTabActivity.tvSchedule.setVisibility(View.GONE);
		} else {
			final String scheduleStr = DateFormat.format("MM/dd/yy",
					this.courseCursor.getColStartDate()
							.longValue())
					+ " - "
					+ DateFormat.format("MM/dd/yy",
							this.courseCursor.getColEndDate()
									.longValue());
			CourseInfoTabActivity.tvSchedule.setText(scheduleStr);
		}
		
		// Meeting Times
		if ((this.courseCursor.getColStartTimeHour() == null)
				|| (this.courseCursor.getColStartTimeMinute() == null)
				|| (this.courseCursor.getColEndTimeHour() == null)
				|| (this.courseCursor.getColEndTimeMinute() == null)) {
			this.findViewById(R.id.textView_classTimes).setVisibility(View.GONE);
			CourseInfoTabActivity.tvMeetingTimes.setVisibility(View.GONE);
		} else {
			final int dayBitField = this.courseCursor.getColDayBitField();
			final StringBuilder builder = new StringBuilder();
			final SimpleTime startTime = new SimpleTime(this.courseCursor.getColStartTimeHour()
					.intValue(),
					this.courseCursor.getColStartTimeMinute()
							.intValue());
			final SimpleTime endTime = new SimpleTime(this.courseCursor.getColEndTimeHour()
					.intValue(),
					this.courseCursor.getColEndTimeMinute()
							.intValue());
			builder.append((dayBitField & DateConstants.SUNDAY_BIT) == DateConstants.SUNDAY_BIT
					? "Su"
					: "");
			builder.append((dayBitField & DateConstants.MONDAY_BIT) == DateConstants.MONDAY_BIT
					? "M"
					: "");
			builder.append((dayBitField & DateConstants.TUESDAY_BIT) == DateConstants.TUESDAY_BIT
					? "Tu"
					: "");
			builder.append((dayBitField & DateConstants.WEDNESDAY_BIT) == DateConstants.WEDNESDAY_BIT
					? "W"
					: "");
			builder.append((dayBitField & DateConstants.THURSDAY_BIT) == DateConstants.THURSDAY_BIT
					? "Th"
					: "");
			builder.append((dayBitField & DateConstants.FRIDAY_BIT) == DateConstants.FRIDAY_BIT
					? "F"
					: "");
			builder.append((dayBitField & DateConstants.SATURDAY_BIT) == DateConstants.SATURDAY_BIT
					? "Sa"
					: "");
			builder.append(" ");
			builder.append(startTime.toString());
			builder.append(" - ");
			builder.append(endTime.toString());
			CourseInfoTabActivity.tvMeetingTimes.setText(builder.toString());
		}
		
		// RSS Feed
		if (this.courseCursor.getColRssFeed() == null) {
			this.findViewById(R.id.textView_rss).setVisibility(View.GONE);
			CourseInfoTabActivity.tvRssFeed.setVisibility(View.GONE);
		} else {
			CourseInfoTabActivity.tvRssFeed.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(final View v) {
					final Intent i = new Intent(Intent.ACTION_VIEW);
					i.setData(Uri.parse(CourseInfoTabActivity.this.courseCursor.getColRssFeed()));
					try {
						CourseInfoTabActivity.this.startActivity(i);
					} catch (final ActivityNotFoundException ex) {
						final Intent chooser = Intent.createChooser(i,
								"Open rss feed...");
						CourseInfoTabActivity.this.startActivity(chooser);
					}
				}
			});
		}
		
		// Overrides
		criteria = new ContentValues();
		criteria.put(CourseTimeOverride.COURSE_ID,
				courseId);
		final CursorCourseTimeOverride courseTimeOverrideCursor = CourseInfoTabActivity.dbHelper.getCourseTimeOverride(criteria,
				new String[] {
						CourseTimeOverride.DATE,
						CourseTimeOverride.START_TIME_HOUR,
						CourseTimeOverride.START_TIME_MINUTE,
						CourseTimeOverride.END_TIME_HOUR,
						CourseTimeOverride.END_TIME_MINUTE },
				true);
		this.startManagingCursor(courseTimeOverrideCursor);
		if (courseTimeOverrideCursor.getCount() < 1) {
			this.findViewById(R.id.textView_overrides).setVisibility(View.GONE);
			CourseInfoTabActivity.lvOverrides.setVisibility(View.GONE);
		} else {
			// Set up the adapter
			final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
					R.layout.item_override,
					courseTimeOverrideCursor,
					new String[] {
							CourseTimeOverride.DATE,
							CourseTimeOverride.START_TIME_HOUR,
							CourseTimeOverride.END_TIME_HOUR },
					new int[] {
							R.id.tv_date,
							R.id.tv_startTime,
							R.id.tv_endTime });
			adapter.setViewBinder(new OverrideViewBinder());
			CourseInfoTabActivity.lvOverrides.setAdapter(adapter);
		}
		
		// Alerts
		criteria = new ContentValues();
		criteria.put(CourseAlert.COURSE_ID,
				Long.valueOf(courseId));
		final CursorCourseAlert courseAlertCursor = CourseInfoTabActivity.dbHelper.getCourseAlert(criteria,
				new String[] { CourseAlert.MINUTES_BEFORE },
				true);
		this.startManagingCursor(courseAlertCursor);
		if (courseAlertCursor.getCount() < 1) {
			this.findViewById(R.id.textView_alerts).setVisibility(View.GONE);
			CourseInfoTabActivity.lvAlerts.setVisibility(View.GONE);
		} else {
			// Set up the adapter
			final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
					R.layout.item_alert,
					courseAlertCursor,
					new String[] { CourseAlert.MINUTES_BEFORE },
					new int[] { R.id.tv_minutesBefore });
			adapter.setViewBinder(new AlertViewBinder());
			CourseInfoTabActivity.lvAlerts.setAdapter(adapter);
		}
		
		// Faculty
		criteria = new ContentValues();
		criteria.put(CourseFaculty.COURSE_ID,
				Long.valueOf(courseId));
		final CursorCourseFaculty courseFacultyCursor = CourseInfoTabActivity.dbHelper.getCourseFaculty(criteria,
				new String[] { CourseFaculty.TYPE, CourseFaculty.FIRST_NAME },
				true);
		this.startManagingCursor(courseFacultyCursor);
		if (courseFacultyCursor.getCount() < 1) {
			this.findViewById(R.id.textView_faculty).setVisibility(View.GONE);
			CourseInfoTabActivity.lvFaculty.setVisibility(View.GONE);
		} else {
			// Set up our adapter
			final CursorAdapter adapter = new SimpleCursorAdapter(this,
					R.layout.course_info_faculty_fill,
					courseFacultyCursor,
					new String[] {
							CourseFaculty.FIRST_NAME,
							CourseFaculty.LAST_NAME,
							CourseFaculty.TYPE },
					new int[] {
							R.id.tv_facFirstName,
							R.id.tv_facLastName,
							R.id.tv_facType });
			CourseInfoTabActivity.lvFaculty.setAdapter(adapter);
			CourseInfoTabActivity.lvFaculty.setOnItemClickListener(new OnItemClickListener() {
				
				@Override
				public void onItemClick(final AdapterView<?> parent,
						final View view,
						final int position,
						final long id) {
					final Intent intent = new Intent(CourseInfoTabActivity.this.getApplicationContext(),
							FacultyActivity.class);
					intent.putExtra(CourseInfoTabActivity.this.getString(R.string.intent_extra_facultyId),
							((CursorCourseFaculty) adapter.getCursor()).getColFacultyId());
					CourseInfoTabActivity.this.startActivity(intent);
				}
			});
		}
		
		// Grade Scale
		if (this.courseCursor.getColGradeScaleName() == null) {
			this.findViewById(R.id.textView_scale).setVisibility(View.GONE);
			CourseInfoTabActivity.tblGradeScale.setVisibility(View.GONE);
		} else {
			criteria = new ContentValues();
			criteria.put(GradingScaleRange.NAME,
					this.courseCursor.getColGradeScaleName());
			final CursorGradingScaleRange gradeScaleRangeCursor = CourseInfoTabActivity.dbHelper.getGradingScaleRange(criteria,
					new String[] { GradingScaleRange.MIN_VALUE },
					false);
			this.startManagingCursor(gradeScaleRangeCursor);
			if (gradeScaleRangeCursor.getCount() < 1) {
				// XXX do I need this again?
				this.findViewById(R.id.textView_scale).setVisibility(View.GONE);
				CourseInfoTabActivity.tblGradeScale.setVisibility(View.GONE);
			} else {
				// Special case for the first item
				final NumberFormat format = new DecimalFormat("0.00");
				final TableRow initialRow = (TableRow) this.getLayoutInflater()
						.inflate(R.layout.gradescale_list_item,
								null);
				((TextView) initialRow.findViewById(R.id.textView_letterGrade)).setText(gradeScaleRangeCursor.getColLetterGrade());
				
				double maxValue;
				double minValue = gradeScaleRangeCursor.getColMinValue();
				((TextView) initialRow.findViewById(R.id.textView_gradeRange)).setText(format.format(minValue)
						+ " +");
				maxValue = minValue - 0.01;
				
				CourseInfoTabActivity.tblGradeScale.addView(initialRow);
				gradeScaleRangeCursor.moveToNext();
				
				// Add the rows
				for (int i = 1; i < gradeScaleRangeCursor.getCount(); ++i) {
					final TableRow row = (TableRow) this.getLayoutInflater()
							.inflate(R.layout.gradescale_list_item,
									null);
					((TextView) row.findViewById(R.id.textView_letterGrade)).setText(gradeScaleRangeCursor.getColLetterGrade());
					
					minValue = gradeScaleRangeCursor.getColMinValue();
					((TextView) row.findViewById(R.id.textView_gradeRange)).setText(format.format(minValue)
							+ " - "
							+ format.format(maxValue));
					maxValue = minValue - 0.01;
					
					CourseInfoTabActivity.tblGradeScale.addView(row);
					gradeScaleRangeCursor.moveToNext();
				}
				gradeScaleRangeCursor.close();
			}
		}
	}
	
	/**
	 * XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		CourseInfoTabActivity.dbHelper.close();
		super.onDestroy();
	}
	
	/**
	 * XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onRestart()
	 */
	@Override
	protected void onRestart() {
		super.onRestart();
		// TODO Q&D fix to get it working
		this.courseCursor.moveToFirst();
	}
	
	/**
	 * XXX
	 */
	private void showDeleteCourseDialog() {
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(R.string.menu_title_delete_course)
				.setMessage("Are you sure you want to delete the course \""
						+ this.courseCursor.getColName()
						+ "\" and all of its associated tasks?")
				.setPositiveButton("Delete",
						new DialogInterface.OnClickListener() {
							
							@SuppressWarnings("synthetic-access")
							@Override
							public void onClick(final DialogInterface dialog,
									final int which) {
								CourseInfoTabActivity.dbHelper.deleteCourse(CourseInfoTabActivity.this.courseCursor.getColId());
								CourseInfoTabActivity.this.finish();
							}
						})
				.setNegativeButton(android.R.string.cancel,
						new CancelListener());
		final AlertDialog alert = builder.create();
		alert.show();
	}
}
